package com.atguigu.tingshu.payment.service.impl;

import com.atguigu.tingshu.account.client.UserAccountFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.account.RechargeInfo;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.order.client.OrderInfoFeignClient;
import com.atguigu.tingshu.payment.config.WxPayV3Config;
import com.atguigu.tingshu.payment.service.PaymentInfoService;
import com.atguigu.tingshu.payment.service.WxPayService;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {

	@Autowired
	private PaymentInfoService paymentInfoService;

	@Autowired
	private RSAAutoCertificateConfig config;

	@Autowired
	private WxPayV3Config wxPayV3Config;

	@Autowired
	private UserInfoFeignClient userInfoFeignClient;

	@Autowired
	private OrderInfoFeignClient orderInfoFeignClient;

	@Autowired
	private UserAccountFeignClient userAccountFeignClient;

	@Override
	public Map<String, Object> createJsapi(String paymentType, String orderNo, Long userId) {
		//	远程调用微信服务器的接口： https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
		//  根据订单编号查询订单对象;
		BigDecimal payAmount = new BigDecimal("0.00");
		// 保存交易记录：1301: 订单支付 1302: 充值 充值金额 recharge_info
		if (paymentType.equals(SystemConstant.PAYMENT_TYPE_ORDER)) {
			//	订单
			Result<OrderInfo> orderInfoResult = this.orderInfoFeignClient.getOrderInfo(orderNo);
			Assert.notNull(orderInfoResult.getData(), "订单信息为空");
			OrderInfo orderInfo = orderInfoResult.getData();
			//  判断订单状态：
			if (orderInfo.getOrderStatus().equals(SystemConstant.ORDER_STATUS_CANCEL)) {
				return new HashMap<>();
			}
			//  赋值支付金额
			payAmount = orderInfo.getOrderAmount();
		} else {
			//	充值
			Result<RechargeInfo> rechargeInfoResult = userAccountFeignClient.getRechargeInfo(orderNo);
			Assert.notNull(rechargeInfoResult.getData(), "充值信息为空");
			payAmount = rechargeInfoResult.getData().getRechargeAmount();
		}
		//  需要传递参数：
		this.paymentInfoService.savePaymentInfo(userId, paymentType, orderNo, payAmount);
		//构建service
		JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
		//跟之前下单示例一样，填充预下单参数
		PrepayRequest request = new PrepayRequest();
		Amount amount = new Amount();
		amount.setTotal(1);
		request.setAmount(amount);
		request.setAppid(wxPayV3Config.getAppid());
		request.setMchid(wxPayV3Config.getMerchantId());
		request.setDescription("测试商品标题");
		request.setNotifyUrl(wxPayV3Config.getNotifyUrl());
		request.setOutTradeNo(orderNo);
		Payer payer = new Payer();
		//	远程调用获取用户信息
		Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
		Assert.notNull(userInfoVoResult.getData(), "用户信息为空");
		String wxOpenId = userInfoVoResult.getData().getWxOpenId();
		payer.setOpenid(wxOpenId);
		request.setPayer(payer);
		//response包含了调起支付所需要的所有参数,可直接用于前端调起支付
		PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
		//声明一个map集合来存储微信支付需要的数据
		Map<String, Object> result = new HashMap<>();
		result.put("timeStamp", response.getTimeStamp()); // 时间戳
		result.put("nonceStr", response.getNonceStr());   // 随机字符串
		result.put("package", response.getPackageVal());  // 订单详情扩展字符串
		result.put("signType", response.getSignType());   // 签名方式
		result.put("paySign", response.getPaySign());     // 签名
		return result;
	}

	@Override
	public Transaction queryPayStatus(String orderNo) {
		// 声明查询对象
		QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
		queryRequest.setMchid(wxPayV3Config.getMerchantId());
		queryRequest.setOutTradeNo(orderNo);
		try {
			//  创建service 对象
			JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
			//  调用查询方法
			Transaction result = service.queryOrderByOutTradeNo(queryRequest);
			System.out.println(result.getTradeState());
			//  返回数据
			return result;
		} catch (ServiceException e) {
			// API返回失败, 例如ORDER_NOT_EXISTS
			System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage());
			System.out.printf("reponse body=[%s]\n", e.getResponseBody());
		}
		return null;
	}
}
